#include "ElevatorControl.hpp"
//创建按钮
Elevator::Elevator()
{
	this->Floor_Btn = new int[this->Floor_Num];
}
//销毁按钮
Elevator::~Elevator()
{
	delete[] this->Floor_Btn;//释放按钮数组空间
}

//获取最低楼层值
int Elevator::Get_MinFloor()
{
	return this->Minimun_Floor;
}
//获取最高楼层值
int Elevator::Get_MaxFloor()
{
	return this->Higest_Floor;
}
//获取楼层总数
int Elevator::Get_FloorNum()
{
	return this->Floor_Num;
}
int Elevator::Get_StopFloor()//获取当前停止楼层
{
	return this->Stop_Floor;
}
void Elevator::Set_StopFloor(int floor)//设置电梯当前停止楼层
{
	//首先限制楼层是否越界
	//1.如果比最低楼层还低就让当前楼层等于最低楼层
	if (floor < this->Get_MinFloor())
	{
		std::cout << "你输入的楼层小于最低楼层,电梯将到达最底层" << endl;
		this->Stop_Floor = this->Get_MinFloor();
	}
	if (floor > this->Get_MaxFloor())
	{
		std::cout << "你输入的楼层大于最高楼层,电梯将到达最高层" << endl;
		this->Stop_Floor = this->Get_MaxFloor();
	}

	this->Stop_Floor = floor;
}
//设置可到达的楼层区间
void Elevator::Set_FloorSection(int min, int max)
{
	this->Minimun_Floor = min;
	this->Higest_Floor = max;
	this->Floor_Num = abs((max - min));
}
void Elevator::Set_MaxWeigh(float num)//设置最大载重量
{
	this->Weight_Max = num;
}
//转换电梯状态
string Elevator::Transform_Enum(State curr)
{
	string state = "";
	switch (curr)
	{
	case Up:
		state = "上升";
		break;
	case Down:
		state = "下降";
		break;
	case Wait:
		state = "等待";
		break;
	}
	return state;
}

//显示当前电梯信息
void Elevator::Show_Elevator()
{
	int start = this->Minimun_Floor;
	string state = this->Transform_Enum(this->Current_State);
	cout << this->Elevator_Name << "信息: " << endl;
	cout << "当前所在楼层-------->" << this->Stop_Floor << "楼" << endl;
	cout << "电梯可到达最高楼层:" << this->Higest_Floor << " 最低楼层: " << this->Minimun_Floor << endl;
	cout << "电梯最大载重量: " << this->Weight_Max << endl;
	cout << "当前可选楼层： "<<endl;//除了所在楼层之外的所有楼层

	//打印了比他小的
	while (start < this->Stop_Floor)
	{
		cout << start << "  ";
		start++;
	}
	//start == Stop_Floor
	while (start <= this->Get_MaxFloor())
	{
		if (start == this->Get_MaxFloor())
		{
			break;
		}
		start++;
		cout << start << "  ";
	}

	cout << endl;
	cout << "电梯初始化完毕----->状态： " << state << endl;
	cout << "电梯门准备--------->状态： " << this->Door_State << endl;
}

void Elevator::Open_Door()//开门操作
{
	this->Door_State = "开启";
	cout << this->Elevator_Name << "梯门准备---------->状态：" << this->Door_State << endl;
	sleep(OPEN_TIME);
	this->Door_State = "关闭";
	cout << this->Elevator_Name << "梯门准备---------->状态：" << this->Door_State << endl;

}

void Elevator::Print_Line(int leng)//打印横线
{
	int index = leng;
	while (index >= 0)
	{
		cout << "-";
		index -= 1;
	}
	cout << endl;
}


void Elevator::Run_Elevator(string dir)//电梯运行
{
	int start = this->Stop_Floor;//获取当前楼层
	int end = 0;
	if (dir == "up")
	{
		end = this->Floor_Btn[this->Floor_Num - 1];//向上取最大值
		for (int i = 0; i <= this->Floor_Num - 1; i++)
		{
			//如果输入的楼层数为0 或者输入的楼层数等于当前楼层数
			if(this->Floor_Btn[i] == 0 || this->Floor_Btn[i] == start)
			{
				continue;
			}
			sleep(UP_TIME);//上升一层楼所需要等待的时间
			this->Current_State = Up;//当前状态是上升
			cout << this->Elevator_Name << "正在上升-------->到达"
				<< this->Floor_Btn[i] << "楼" << endl;
			//开启电梯门后的操作
			this->Open_Door();
			//到达最后的楼层停止
			if (this->Floor_Btn[i] == end)
			{
				Up_Button = false;
				this->Stop_Floor = end;//电梯所在的楼层位置
				this->Current_State = Wait;
				cout << Up_Button << endl;
				this->Show_Elevator();
				break;
			}
		}
	}



	if (dir == "down")
	{
		end = this->Floor_Btn[0];//向下取最小
		for (int j = start; j >= this->Minimun_Floor; j--)
		{
			if (this->Floor_Btn[j] == 0 || this->Floor_Btn[j] == start)
			{
				continue;
			}
			sleep(UP_TIME);
			this->Current_State = Down;
			cout << this->Elevator_Name << "正在下降-------->到达" << this->Floor_Btn[j] << "楼" << endl;
			//开启电梯门后的操作
			this->Open_Door();

			//到达最后楼层停止
			if (this->Floor_Btn[j] == end)
			{
				Down_Button = false;
				this->Stop_Floor = j;
				this->Current_State = Wait;
				break;
			}
		}

	}

}

//楼层输入
int* Input_FloorInduce(Elevator* ele)
{
	int end = 0;
	int count = 0;//计数【用于剔除多输入的楼层数】
	char num = '0';
	string numstr = "";
	stringstream strnum;
	int leng = ele->Get_FloorNum();
	char* floors = new char[leng * 3];
	int* floors_num = new int[leng];
	end = leng * 3;
	cout << "请输入要到达的楼层[使用空格间隔]:" << endl;
	cin.getline(floors, leng * 3, '\n');
	for (int i = 0; i < end; i++)
	{
		num = *(floors + i);
		if (num != ' ' && num != '\0') {
			numstr += num;
		}
		if (num == ' ' || num == '\0') {
			strnum << numstr;
			strnum >> *(floors_num + count);  // 将转换的数字赋值入数组
			//cout << *(floors_num + count) << endl;
			numstr = "";
			count += 1;
			strnum.clear();  //多次调用需要清空缓冲区
			if (num == '\0' || count == leng) {
				break;
			}
		}
	}
	//局部变量会自动销毁
	//delete []floors;
	return floors_num;
}
void Elevator::Input_FloorBtn(Elevator* ele)//楼层按钮操作
{
	int leng = this->Floor_Num;//总楼层
	int* induce = nullptr;
	int* temp = nullptr;
	induce = Input_FloorInduce(ele);
	temp = ele->Floor_Btn;
	//排序 [从小到大排]
	for (int i = 0; i < leng; ++i)
	{
		for (int j = 0; j < leng - 1; ++j)
		{
			if (*(induce + j) < ele->Minimun_Floor)
			{
				*(induce + j) = 0;
			}
			if (*(induce + j) > *(induce + j + 1))
			{
				int temp = *(induce + j);
				*(induce + j) = *(induce + j + 1);
				*(induce + j + 1) = temp;
			}
		}
	}

	//将排序好的楼层序列赋值入电梯对象重的按下楼层数组
	for (int k = 0; k < leng; k++)
	{
		*(temp + k) = *(induce + k);
		//if(*(temp + k) != 0) 把0也要打印出来
		cout << *(temp + k) << "  ";
	}
	cout << endl;
	//释放空间
	induce = nullptr;
	temp = nullptr;
}

//上行下行总输入方法
void Input_TotalDircton()
{
	string btn = "";
	while (true)
	{
		cout << "请输入需要的方向[up/down/up_down]:";
		cin >> btn;
		cin.clear();
		cin.ignore();
		if (btn == "up") {
			Up_Button = true;
			return;
		}
		if (btn == "down") {
			Down_Button = true;
			return;
		}
		if (btn == "up_down") {
			Down_Button = true;
			Up_Button = true;
			return;
		}
		cout << "输入不正确请重新输入!" << endl;
	}
}

void Show_Run(Elevator* ele, string dir)
{
	ele->Run_Elevator(dir);
}


//筛选当前可执行的电梯
void Choice_Elevator(Elevator* ele[])
{
	int end = 0;
	Elevator* temp = nullptr;
	bool is_up = Up_Button;
	bool is_down = Down_Button;
	for (int i = 0; i < ElevatorSum; i++)
	{
		temp = ele[i];
		if (temp->Current_State == Wait)
		{
			if (is_up == true)
			{
				//上行
				if (temp->Get_StopFloor() < temp->Get_MaxFloor())
				{
					temp->Input_FloorBtn(temp);
					//创建线程
					thread Ele_1(Show_Run, temp, "up");
					Ele_1.join();
					continue;
				}
			}
			if (is_down == true)
			{
				if (temp->Get_StopFloor() > temp->Get_MinFloor())
				{
					temp->Input_FloorBtn(temp);
					thread Ele_2(Show_Run, temp, "down");
					Ele_2.join();
					continue;
				}
			}
		}
	}
}

//定时器
void  Timer(void(*call)(Elevator* arr[]), Elevator* ele[], int interval) {
	while (true)
	{
		Input_TotalDircton();
		sleep(interval);
		call(ele);
	}
}